#include "ShockWave.h"
#include "OgreStringConverter.h"
#include "OgreMath.h"

Ogre::Real ShockWave::systemName = 0;
ShockWave::ShockWave(Ogre::SceneManager * mSceneManager, Ogre::String file, Ogre::Real shockheight, Ogre::Real shockspeed)  {
	systemName = 0;
	_mScene = mSceneManager;
	_directionChanged = true;
	_started = false;
	startingAngle = 0;
	shockWaveFile = file;
	shockHeight = shockheight;
	shockSpeed = shockspeed;
	
}


ShockWave::~ShockWave(void) {}

void ShockWave::prepareEvent() {
	ShockWave::systemName++;
	_dustFar = _mScene->createParticleSystem("ShockWave " + Ogre::StringConverter::toString(ShockWave::systemName) + "Far", shockWaveFile);
	ShockWave::systemName++;
	_dustNear = _mScene->createParticleSystem("ShockWave " + Ogre::StringConverter::toString(ShockWave::systemName) +"Near", shockWaveFile);
	_dustNodeNear = _mScene->createSceneNode();
	_dustNodeFar = _mScene->createSceneNode();
	_dustNodeNear->attachObject(_dustNear);
	_dustNodeFar->attachObject(_dustFar);
	_dustNodeFar->translate(0,shockHeight,0);
	_dustNodeNear->translate(0,shockHeight,0);
	_dustNear->setRenderQueueGroup(Ogre::RENDER_QUEUE_8);
	_dustFar->setRenderQueueGroup(Ogre::RENDER_QUEUE_6);

}

void ShockWave::startEvent() {

	_mScene->getRootSceneNode()->createChildSceneNode()->addChild(_dustNodeNear);
	_mScene->getRootSceneNode()->createChildSceneNode()->addChild(_dustNodeFar);
	_dustNear->fastForward(1);
	_dustFar->fastForward(1);
	_started = true;
	Ogre::Real totalParticles = _dustNear->getNumParticles();
	_dustFar->setParticleQuota(totalParticles);
	_dustNear->setParticleQuota(totalParticles);
	Ogre::Real increments = (Ogre::Real) 360/(totalParticles * 2);
	Ogre::Particle *p;
	Ogre::Real angleInc = 0;
	if(startingAngle == 0) {
		angleInc = -90;
	}
	else {
		angleInc = startingAngle - 90;
	}
	for(int i = 0; i < totalParticles; i++, angleInc = angleInc + increments) {
		
		p = _dustNear->getParticle(i);
		Ogre::Vector3 temp = Ogre::Vector3(Ogre::Math::Cos(Ogre::Degree(angleInc)),0, Ogre::Math::Sin(Ogre::Degree(angleInc)));
		p->direction = temp*shockSpeed;

	}
	for(int i = 0; i < totalParticles; i++, angleInc = angleInc + increments) {
		p = _dustFar->getParticle(i);
		Ogre::Vector3 temp = Ogre::Vector3(Ogre::Math::Cos(Ogre::Degree(angleInc)),0, Ogre::Math::Sin(Ogre::Degree(angleInc)));
		p->direction = temp*shockSpeed;

	}
}

void ShockWave::restartEvent() {
	this->prepareEvent();
	this->startEvent();
}

bool ShockWave::hasStarted() {
	return _started;
}

Ogre::Real ShockWave::getParticleDistanceFromCenter() {
	if(_dustFar != nullptr && _dustFar->getParticle(0) != nullptr) {
		Ogre::Particle *p = _dustFar->getParticle(0);
		Ogre::Vector3 tmp = Ogre::Vector3(p->position.x,0,p->position.z);
		return tmp.length();
	}
	return 99999999;
}

Ogre::Real ShockWave::getSquaredParticleDistanceFromCenter() {
	if(_dustFar != nullptr && _dustFar->getParticle(0) != nullptr) {
		Ogre::Particle *p = _dustFar->getParticle(0);
		Ogre::Vector3 tmp = Ogre::Vector3(p->position.x,0,p->position.z);
		return tmp.squaredLength();
	}
	return 99999999;
}

void ShockWave::setStartingAngle(Ogre::Radian rad) {
	startingAngle = Ogre::Math::RadiansToDegrees(rad.valueDegrees());
}

void ShockWave::update(float deltaTime) {

}

void ShockWave::quit() {
	_started = false;
}
